package cn.iotab.iotkit.transport.api.access.model.message;

import cn.iotab.iotkit.transport.api.access.model.exception.IncompleteMessageException;
import com.alibaba.fastjson.JSONObject;

import javax.validation.constraints.NotNull;

/**
 * @author zhouhao
 * @since 1.0.0
 */
public class CommonDeviceMessageReply implements DeviceMessageReply, MessageReplyCodec {

    private String productKey;
    private String deviceId;

    private OriginMessageReply messageReply;

    private long timestamp;

    public CommonDeviceMessageReply() {
        this.messageReply = new OriginMessageReply();
    }

    @Override
    public void fromOriginMessageReply(String productKey, String deviceId, OriginMessageReply messageReply) {
        this.productKey = productKey;
        this.deviceId = deviceId;
        this.messageReply.from(messageReply);
        this.timestamp = messageReply.getTs() == null ? System.currentTimeMillis() : messageReply.getTs();
    }

    @Override
    public OriginMessageReply toOriginMessageReply() {
        if (timestamp > 0) {
            messageReply.setTs(timestamp);
        }
        try {
            messageReply.validate();
        } catch (Exception e) {
            throw new IncompleteMessageException("messageReply format error, cause="
                    + e.getMessage() + ", messageReply: " + messageReply);
        }
        return messageReply;
    }


    @Override
    public String getMessageId() {
        return messageReply.getId();
    }

    public void setMessageId(String messageId) {
        this.messageReply.setId(messageId);
    }

    @Override
    public String getProductKey() {
        return productKey;
    }

    public void setProductKey(String productKey) {
        this.productKey = productKey;
    }

    @Override
    public String getDeviceId() {
        return deviceId;
    }

    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }

    @Override
    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long ts) {
        this.timestamp = ts;
    }

    @Override
    public Integer getCode() {
        return this.messageReply.getCode();
    }

    @Override
    public void setCode(Integer code) {
        this.messageReply.setCode(code);
    }

    @Override
    public String getErrorMsg() {
        return this.messageReply.getErr();
    }

    public void setErrorMsg(String error) {
        this.messageReply.setErr(error);
    }

    @Override
    public JSONObject getData() {
        return this.messageReply.getData();
    }

    public void setData(JSONObject object) {
        this.messageReply.setData(object);
    }

    @Override
    public DeviceMessageReply from(@NotNull DeviceMessage message) {
        this.deviceId = message.getDeviceId();
        this.productKey = message.getProductKey();
        this.messageReply = new OriginMessageReply();
        this.setMessageId(message.getMessageId());
        return this;
    }

    public static DeviceMessageReply commonErrorReply(@NotNull DeviceMessage message, int code, String error) {
        CommonDeviceMessageReply reply = new CommonDeviceMessageReply();
        reply.from(message);
        reply.setCode(code);
        reply.setTimestamp(System.currentTimeMillis());
        reply.setErrorMsg(error);
        return reply;
    }

}
